﻿Imports System.Drawing
Imports System.Windows.Forms

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class cTreeView
    Inherits System.Windows.Forms.TreeView

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.SetStyle(Windows.Forms.ControlStyles.SupportsTransparentBackColor, True)
        Me.SetStyle(Windows.Forms.ControlStyles.OptimizedDoubleBuffer, True)
        Me.SetStyle(Windows.Forms.ControlStyles.ResizeRedraw, True)
        Me.ResizeRedraw = True
        'Me.DrawMode = Windows.Forms.TreeViewDrawMode.OwnerDrawText

    End Sub

#Region "Designer Generated Code"
    'UserControl overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private WithEvents components As System.Windows.Forms.TreeView

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.components = New System.Windows.Forms.TreeView()
        Me.SuspendLayout()
        '
        'components
        '
        Me.components.Location = New System.Drawing.Point(0, 0)
        Me.components.Name = "cTreeView"
        Me.components.Size = New System.Drawing.Size(100, 23)
        Me.components.TabIndex = 0
        '
        'PictureBox
        '
        Me.Name = "cTreeView"
        Me.ResumeLayout(False)
    End Sub
#End Region

#Region "Declarations"
    Dim mxNode As cTreeViewNode = Nothing
    Public Event ActionButtonClicked(Node As cTreeViewNode, actionButton As ActionButtonTypesEnum)
#End Region

#Region "Overriden Procedures"
    Protected Overrides Sub OnDrawNode(e As System.Windows.Forms.DrawTreeNodeEventArgs)
        MyBase.OnDrawNode(e)

        If TypeOf e.Node Is cTreeViewNode Then

            'Get the actual bounds and node
            Dim actualBounds As Rectangle = e.Bounds
            Dim ctNode As cTreeViewNode = e.Node

            'Draw background
            If (e.State And TreeNodeStates.Selected) = TreeNodeStates.Selected Then
                e.Graphics.FillRectangle(New SolidBrush(ctNode.BackColorSelected), actualBounds)
            Else
                e.Graphics.FillRectangle(New SolidBrush(ctNode.BackColorNormal), actualBounds)
            End If

            'Draw the node text
            If (e.State And TreeNodeStates.Selected) = TreeNodeStates.Selected Then
                e.Graphics.DrawString(e.Node.Text, ctNode.Font, New SolidBrush(ctNode.ForeColorSelected), e.Bounds.Left - 2, e.Bounds.Top)
            Else
                e.Graphics.DrawString(e.Node.Text, ctNode.Font, New SolidBrush(ctNode.ForeColorNormal), e.Bounds.Left - 2, e.Bounds.Top)
            End If

        Else
            e.DrawDefault = True
        End If

    End Sub
    Protected Overrides Sub OnMouseUp(e As System.Windows.Forms.MouseEventArgs)
        MyBase.OnMouseUp(e)
        Dim curNode As TreeNode = Me.GetNodeAt(e.X, e.Y)
        If curNode IsNot Nothing Then
            If TypeOf curNode Is cTreeViewNode Then
                Dim ctNode As cTreeViewNode = curNode
                If ctNode.ActionButton <> ActionButtonTypesEnum.None Then
                    'check if it hit the button
                    Dim rect As New Rectangle(ctNode.Bounds.Left + ctNode.Bounds.Width + ctNode.Bounds.Height, _
                                              ctNode.Bounds.Top, _
                                              ctNode.Bounds.Height, _
                                              ctNode.Bounds.Height)
                    If rect.Contains(e.X, e.Y) Then
                        RaiseEvent ActionButtonClicked(ctNode, ctNode.ActionButton)
                    End If
                End If
            End If
        End If
    End Sub
    Protected Overrides Sub OnMouseMove(e As System.Windows.Forms.MouseEventArgs)
        MyBase.OnMouseMove(e)
        Dim curNode As TreeNode = Me.GetNodeAt(e.X, e.Y)
        If curNode Is Nothing Then
            If Me.mxNode IsNot Nothing Then
                EraseActionButton()
                Me.mxNode = Nothing
            End If
        Else
            If (TypeOf curNode Is cTreeViewNode) _
                AndAlso (CType(curNode, cTreeViewNode).ActionButton <> ActionButtonTypesEnum.None) Then
                If Me.mxNode IsNot Nothing Then
                    If Me.mxNode.Bounds.Contains(e.X, e.Y) Then
                    Else
                        EraseActionButton()
                        Me.mxNode = curNode
                        DrawActionButtonNormal()
                    End If
                Else
                    Me.mxNode = curNode
                    DrawActionButtonNormal()
                End If
            Else
                If Me.mxNode IsNot Nothing Then
                    EraseActionButton()
                    Me.mxNode = Nothing
                End If
            End If
        End If
    End Sub
#End Region

#Region "Private Procedures"
    Private Sub DrawActionButtonNormal()
        Dim g As Graphics = Me.CreateGraphics
        Dim rect As New Rectangle(Me.mxNode.Bounds.Left + Me.mxNode.Bounds.Width + Me.mxNode.Bounds.Height, _
                                  Me.mxNode.Bounds.Top, _
                                  Me.mxNode.Bounds.Height, _
                                  Me.mxNode.Bounds.Height)
        Dim butImage As Image = Nothing
        Select Case Me.mxNode.ActionButton
            Case Is = ActionButtonTypesEnum.Add
                butImage = My.Resources.Icon_Add_Normal
            Case Is = ActionButtonTypesEnum.Edit
                butImage = My.Resources.Icon_Edit_Normal
            Case Is = ActionButtonTypesEnum.Delete
                butImage = My.Resources.Icon_Delete_Normal
            Case Is = ActionButtonTypesEnum.Cancel
                butImage = My.Resources.Icon_Cancel_Normal
            Case Is = ActionButtonTypesEnum.Save
                butImage = My.Resources.Icon_Save_Normal
            Case Is = ActionButtonTypesEnum.Copy
                butImage = My.Resources.Icon_Copy_Normal
        End Select
        g.DrawImage(butImage, rect)
    End Sub
    Private Sub EraseActionButton()
        Dim g As Graphics = Me.CreateGraphics
        Dim rect As New Rectangle(Me.mxNode.Bounds.X + Me.mxNode.Bounds.Width + Me.mxNode.Bounds.Height, _
                                   Me.mxNode.Bounds.Y, _
                                   Me.mxNode.Bounds.Height + 10, _
                                   Me.mxNode.Bounds.Height + 1)
        g.FillRectangle(New SolidBrush(Me.BackColor), rect)
    End Sub
#End Region

End Class

Public Class cTreeViewNode
    Inherits Windows.Forms.TreeNode

    Private iBackColorNormal As Color = SystemColors.InactiveBorder
    Public Property BackColorNormal As Color
        Get
            Return Me.iBackColorNormal
        End Get
        Set(value As Color)
            Me.iBackColorNormal = value
        End Set
    End Property

    Private iForeColorNormal As Color = SystemColors.ControlText
    Public Property ForeColorNormal As Color
        Get
            Return Me.iForeColorNormal
        End Get
        Set(value As Color)
            Me.iForeColorNormal = value
        End Set
    End Property

    Private iBackColorSelected As Color = SystemColors.Highlight
    Public Property BackColorSelected As Color
        Get
            Return Me.iBackColorSelected
        End Get
        Set(value As Color)
            Me.iBackColorSelected = value
        End Set
    End Property

    Private iForeColorSelected As Color = SystemColors.HighlightText
    Public Property ForeColorSelected As Color
        Get
            Return Me.iForeColorSelected
        End Get
        Set(value As Color)
            Me.iForeColorSelected = value
        End Set
    End Property

    Private iFont As Font = New Font("Microsoft Sans Serif", 8.25)
    Public Property Font As Font
        Get
            Return Me.iFont
        End Get
        Set(value As Font)
            Me.iFont = value
        End Set
    End Property

    Private iDataObject As Object
    Public Property DataObject As Object
        Get
            Return Me.iDataObject
        End Get
        Set(value As Object)
            Me.iDataObject = value
        End Set
    End Property

    Private iActionButton As ActionButtonTypesEnum = ActionButtonTypesEnum.Add
    Public Property ActionButton As ActionButtonTypesEnum
        Get
            Return Me.iActionButton
        End Get
        Set(value As ActionButtonTypesEnum)
            Me.iActionButton = value
        End Set
    End Property

    Private iNodeType As Object
    Public ReadOnly Property NodeType As Object
        Get
            Return Me.iNodeType
        End Get
    End Property

    Public Sub New(text As String, _
                   nodetype As Object, _
                   Optional ActionButton As ActionButtonTypesEnum = ActionButtonTypesEnum.None, _
                   Optional DataObject As Object = Nothing)
        MyBase.New(text)
        Me.iNodeType = nodetype
        Me.iActionButton = ActionButton
        Me.iDataObject = DataObject
    End Sub


End Class

Public Enum ActionButtonTypesEnum
    None
    Add
    Edit
    Delete
    Cancel
    Save
    Copy
End Enum


